#include "Clip.h"
#include <iostream>

using namespace std;

/*
 * Konstruktor. Bekommt einen HUD und die Raumgrenzen übergeben.
 */

Clip::Clip(const double clipXmin, const double clipXmax, const double clipYmin,
		const double clipYmax, const double clipZmin, const double clipZmax, HUD * hud):
		_hud(hud), noClip(false) {
	clipX[0] = clipXmin;
	clipX[1] = clipXmax;
	clipY[0] = clipYmin;
	clipY[1] = clipYmax;
	clipZ[0] = clipZmin;
	clipZ[1] = clipZmax;
	_hud->setText(1, "Clipping on");
}

Clip::~Clip(){
#ifdef DEBUG
	cout << "----- Destruiert: Clip -----" << endl;
#endif
}

/*
 * Prüft, ob die neue Kameraposition zulässig ist.
 */

bool Clip::posValid(const osg::Vec3d pos){
	if (noClip){
		_hud->setText(2, "");
		return true;
	}
	if (inRoom(pos) && !collision(pos)){
		_hud->setText(2, "");
		return true;
	}
	else {
		_hud->setText(2, "Collision");
		return false;
	}
}

/*
 * Prüft, ob die Kamera außerhalb des Raumes gesetzt werden soll.
 * Returnt true, bei zulässigen Bewegungen und false bei unzulässigen.
 */

bool Clip::inRoom(const osg::Vec3d pos){
	if (pos.x() < clipX[0] || pos.x() > clipX[1]){
			#ifdef DEBUG
			cout << "Clipping boarder reached!" << endl;
			#endif
			return false;
		}
	if (pos.y() < clipY[0] || pos.y() > clipY[1]){
			#ifdef DEBUG
			cout << "Clipping boarder reached!" << endl;
			#endif
			return false;
		}
	if (pos.z() < clipZ[0] || pos.z() > clipZ[1]){
			#ifdef DEBUG
			cout << "Clipping boarder reached!" << endl;
			#endif
			return false;
		}
	return true;
}

/*
 * Erzeugt eine BoundingSphere an der Kameraposition und
 * prüft, ob diese mit irgendeinem Objekt aus dem
 * Objekt-Vector kollidiert.
 * Returnt true bei einer erkannten Kollision.
 */

bool Clip::collision(const osg::Vec3d pos){
	eyeSphere = osg::BoundingSphere(pos, 1);

	for (vector<osg::BoundingSphere>::iterator i =
		boundingSpheres.begin(); i != boundingSpheres.end();
			++i){

		if (eyeSphere.intersects(*i)){
			#ifdef DEBUG
			cout << "Collision!" << endl;
			#endif
			return true;
		}
	}
	return false;
}

/*
 * Schaltet das Clipping ein- und aus.
 */

void Clip::clipSwitch(){
	noClip = !noClip;
	if (noClip){
		#ifdef DEBUG
		cout << "Clipping off" << endl;
		#endif
		_hud->setText(1, "Clipping off");
	}
	else{
		#ifdef DEBUG
		cout << "Clipping on" << endl;
		#endif
		_hud->setText(1, "Clipping on");
	}
}

/*
 * Methode zum Einfügen von BoundingSpheres in den
 * Objekt-Vektor.
 */

void Clip::addBoundingSphere(const osg::BoundingSphere sphere){
	boundingSpheres.push_back (sphere);
}
